﻿using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Dynamic;
using System.Text;
using System.Threading.Tasks;

namespace Helpers.Extensions
{
    public static class EntityFrameworkExt
    {
        public static async Task<IEnumerable<dynamic>> SqlQueryDynamic(this DbContext db, string Sql, params SqlParameter[] parameters)
        {
            using (var cmd = db.Database.GetDbConnection().CreateCommand())
            {
                using (cmd.Connection)
                {
                    cmd.CommandText = Sql;
                    if (cmd.Connection.State != ConnectionState.Open)
                    {
                        cmd.Connection.Open();
                    }

                    foreach (var p in parameters)
                    {
                        var dbParameter = cmd.CreateParameter();
                        dbParameter.DbType = p.DbType;
                        dbParameter.ParameterName = p.ParameterName;
                        dbParameter.Value = p.Value;
                        cmd.Parameters.Add(dbParameter);
                    }

                    List<dynamic> result = new List<dynamic>();
                    using (var dataReader = await cmd.ExecuteReaderAsync())
                    {
                        while (await dataReader.ReadAsync())
                        {
                            var row = new ExpandoObject() as IDictionary<string, object>;
                            for (var fieldCount = 0; fieldCount < dataReader.FieldCount; fieldCount++)
                            {
                                row.Add(dataReader.GetName(fieldCount), dataReader[fieldCount]);
                            }
                            result.Add(row);
                        }
                    }
                    return result;
                }
            }
        }

        //public static InjectDbContext(this IServiceCollection)

        //public static async Task UsingDbContextPoolAsync<T>(this IServiceProvider provider, Func<T, Task> func) where T : DbContext
        //{
        //    var pool = provider.GetRequiredService<DbContextPool<T>>();
        //    var db = pool.Rent();
        //    try
        //    {
        //        await func(db);
        //    }
        //    catch (Exception)
        //    {
        //        throw;
        //    }
        //    finally
        //    {
        //        pool.Return(db);
        //    }
        //}

        //public static Task UsingDbContextPoolAsync<T>(this IServiceProvider provider, Action<T> action) where T : DbContext
        //{
        //    return UsingDbContextPoolAsync<T>(provider, it => Task.Run(() => action(it)));
        //}
    }
}

